home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / PIL / PngImagePlugin.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  14KB  |  444 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __version__ = '0.8.2'
  5. import re
  6. import string
  7. import Image
  8. import ImageFile
  9. import ImagePalette
  10.  
  11. def i16(c):
  12.     return ord(c[1]) + (ord(c[0]) << 8)
  13.  
  14.  
  15. def i32(c):
  16.     return ord(c[3]) + (ord(c[2]) << 8) + (ord(c[1]) << 16) + (ord(c[0]) << 24)
  17.  
  18. is_cid = re.compile('\\w\\w\\w\\w').match
  19. _MAGIC = '\x89PNG\r\n\x1a\n'
  20. _MODES = {
  21.     (1, 0): ('1', '1'),
  22.     (2, 0): ('L', 'L;2'),
  23.     (4, 0): ('L', 'L;4'),
  24.     (8, 0): ('L', 'L'),
  25.     (16, 0): ('I', 'I;16B'),
  26.     (8, 2): ('RGB', 'RGB'),
  27.     (16, 2): ('RGB', 'RGB;16B'),
  28.     (1, 3): ('P', 'P;1'),
  29.     (2, 3): ('P', 'P;2'),
  30.     (4, 3): ('P', 'P;4'),
  31.     (8, 3): ('P', 'P'),
  32.     (8, 4): ('LA', 'LA'),
  33.     (16, 4): ('RGBA', 'LA;16B'),
  34.     (8, 6): ('RGBA', 'RGBA'),
  35.     (16, 6): ('RGBA', 'RGBA;16B') }
  36.  
  37. class ChunkStream:
  38.     
  39.     def __init__(self, fp):
  40.         self.fp = fp
  41.         self.queue = []
  42.         if not hasattr(Image.core, 'crc32'):
  43.             self.crc = self.crc_skip
  44.         
  45.  
  46.     
  47.     def read(self):
  48.         if self.queue:
  49.             (cid, pos, len) = self.queue[-1]
  50.             del self.queue[-1]
  51.             self.fp.seek(pos)
  52.         else:
  53.             s = self.fp.read(8)
  54.             cid = s[4:]
  55.             pos = self.fp.tell()
  56.             len = i32(s)
  57.         if not is_cid(cid):
  58.             raise SyntaxError, 'broken PNG file (chunk %s)' % repr(cid)
  59.         
  60.         return (cid, pos, len)
  61.  
  62.     
  63.     def close(self):
  64.         self.queue = None
  65.         self.crc = None
  66.         self.fp = None
  67.  
  68.     
  69.     def push(self, cid, pos, len):
  70.         self.queue.append((cid, pos, len))
  71.  
  72.     
  73.     def call(self, cid, pos, len):
  74.         if Image.DEBUG:
  75.             print 'STREAM', cid, pos, len
  76.         
  77.         return getattr(self, 'chunk_' + cid)(pos, len)
  78.  
  79.     
  80.     def crc(self, cid, data):
  81.         crc1 = Image.core.crc32(data, Image.core.crc32(cid))
  82.         crc2 = (i16(self.fp.read(2)), i16(self.fp.read(2)))
  83.         if crc1 != crc2:
  84.             raise SyntaxError, 'broken PNG file(bad header checksum in %s)' % cid
  85.         
  86.  
  87.     
  88.     def crc_skip(self, cid, data):
  89.         self.fp.read(4)
  90.  
  91.     
  92.     def verify(self, endchunk = 'IEND'):
  93.         cids = []
  94.         while None:
  95.             (cid, pos, len) = self.read()
  96.             if cid == endchunk:
  97.                 break
  98.             
  99.             cids.append(cid)
  100.             continue
  101.             return cids
  102.  
  103.  
  104.  
  105. class PngInfo:
  106.     
  107.     def __init__(self):
  108.         self.chunks = []
  109.  
  110.     
  111.     def add(self, cid, data):
  112.         self.chunks.append((cid, data))
  113.  
  114.     
  115.     def add_text(self, key, value, zip = 0):
  116.         if zip:
  117.             import zlib as zlib
  118.             self.add('zTXt', key + '\x00\x00' + zlib.compress(value))
  119.         else:
  120.             self.add('tEXt', key + '\x00' + value)
  121.  
  122.  
  123.  
  124. class PngStream(ChunkStream):
  125.     
  126.     def __init__(self, fp):
  127.         ChunkStream.__init__(self, fp)
  128.         self.im_info = { }
  129.         self.im_size = (0, 0)
  130.         self.im_mode = None
  131.         self.im_tile = None
  132.         self.im_palette = None
  133.  
  134.     
  135.     def chunk_IHDR(self, pos, len):
  136.         s = ImageFile._safe_read(self.fp, len)
  137.         self.im_size = (i32(s), i32(s[4:]))
  138.         
  139.         try:
  140.             (self.im_mode, self.im_rawmode) = _MODES[(ord(s[8]), ord(s[9]))]
  141.         except:
  142.             pass
  143.  
  144.         if ord(s[12]):
  145.             self.im_info['interlace'] = 1
  146.         
  147.         if ord(s[11]):
  148.             raise SyntaxError, 'unknown filter category'
  149.         
  150.         return s
  151.  
  152.     
  153.     def chunk_IDAT(self, pos, len):
  154.         self.im_tile = [
  155.             ('zip', (0, 0) + self.im_size, pos, self.im_rawmode)]
  156.         self.im_idat = len
  157.         raise EOFError
  158.  
  159.     
  160.     def chunk_IEND(self, pos, len):
  161.         raise EOFError
  162.  
  163.     
  164.     def chunk_PLTE(self, pos, len):
  165.         s = ImageFile._safe_read(self.fp, len)
  166.         if self.im_mode == 'P':
  167.             self.im_palette = ('RGB', s)
  168.         
  169.         return s
  170.  
  171.     
  172.     def chunk_tRNS(self, pos, len):
  173.         s = ImageFile._safe_read(self.fp, len)
  174.         if self.im_mode == 'P':
  175.             i = string.find(s, chr(0))
  176.             if i >= 0:
  177.                 self.im_info['transparency'] = i
  178.             
  179.         elif self.im_mode == 'L':
  180.             self.im_info['transparency'] = i16(s)
  181.         
  182.         return s
  183.  
  184.     
  185.     def chunk_gAMA(self, pos, len):
  186.         s = ImageFile._safe_read(self.fp, len)
  187.         self.im_info['gamma'] = i32(s) / 100000
  188.         return s
  189.  
  190.     
  191.     def chunk_pHYs(self, pos, len):
  192.         s = ImageFile._safe_read(self.fp, len)
  193.         px = i32(s)
  194.         py = i32(s[4:])
  195.         unit = ord(s[8])
  196.         if unit == 1:
  197.             dpi = (int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5))
  198.             self.im_info['dpi'] = dpi
  199.         elif unit == 0:
  200.             self.im_info['aspect'] = (px, py)
  201.         
  202.         return s
  203.  
  204.     
  205.     def chunk_tEXt(self, pos, len):
  206.         s = ImageFile._safe_read(self.fp, len)
  207.         
  208.         try:
  209.             (k, v) = string.split(s, '\x00', 1)
  210.         except ValueError:
  211.             k = s
  212.             v = ''
  213.  
  214.         if k:
  215.             self.im_info[k] = v
  216.         
  217.         return s
  218.  
  219.  
  220.  
  221. def _accept(prefix):
  222.     return prefix[:8] == _MAGIC
  223.  
  224.  
  225. class PngImageFile(ImageFile.ImageFile):
  226.     format = 'PNG'
  227.     format_description = 'Portable network graphics'
  228.     
  229.     def _open(self):
  230.         if self.fp.read(8) != _MAGIC:
  231.             raise SyntaxError, 'not a PNG file'
  232.         
  233.         self.png = PngStream(self.fp)
  234.         while None:
  235.             (cid, pos, len) = self.png.read()
  236.             
  237.             try:
  238.                 s = self.png.call(cid, pos, len)
  239.             except EOFError:
  240.                 break
  241.             except AttributeError:
  242.                 if Image.DEBUG:
  243.                     print cid, pos, len, '(unknown)'
  244.                 
  245.                 s = ImageFile._safe_read(self.fp, len)
  246.  
  247.             continue
  248.             self.mode = self.png.im_mode
  249.             self.size = self.png.im_size
  250.             self.info = self.png.im_info
  251.             self.tile = self.png.im_tile
  252.             if self.png.im_palette:
  253.                 (rawmode, data) = self.png.im_palette
  254.                 self.palette = ImagePalette.raw(rawmode, data)
  255.             
  256.         self._PngImageFile__idat = len
  257.  
  258.     
  259.     def verify(self):
  260.         if self.fp is None:
  261.             raise RuntimeError('verify must be called directly after open')
  262.         
  263.         self.fp.seek(self.tile[0][2] - 8)
  264.         self.png.verify()
  265.         self.png.close()
  266.         self.fp = None
  267.  
  268.     
  269.     def load_prepare(self):
  270.         if self.info.get('interlace'):
  271.             raise IOError('cannot read interlaced PNG files')
  272.         
  273.         ImageFile.ImageFile.load_prepare(self)
  274.  
  275.     
  276.     def load_read(self, bytes):
  277.         while self._PngImageFile__idat == 0:
  278.             self.fp.read(4)
  279.             (cid, pos, len) = self.png.read()
  280.             if cid not in ('IDAT', 'DDAT'):
  281.                 self.png.push(cid, pos, len)
  282.                 return ''
  283.             
  284.             self._PngImageFile__idat = len
  285.         if bytes <= 0:
  286.             bytes = self._PngImageFile__idat
  287.         else:
  288.             bytes = min(bytes, self._PngImageFile__idat)
  289.         self._PngImageFile__idat = self._PngImageFile__idat - bytes
  290.         return self.fp.read(bytes)
  291.  
  292.     
  293.     def load_end(self):
  294.         self.png.close()
  295.         self.png = None
  296.  
  297.  
  298.  
  299. def o16(i):
  300.     return chr(i >> 8 & 255) + chr(i & 255)
  301.  
  302.  
  303. def o32(i):
  304.     return chr(i >> 24 & 255) + chr(i >> 16 & 255) + chr(i >> 8 & 255) + chr(i & 255)
  305.  
  306. _OUTMODES = {
  307.     '1': ('1', chr(1) + chr(0)),
  308.     'L;1': ('L;1', chr(1) + chr(0)),
  309.     'L;2': ('L;2', chr(2) + chr(0)),
  310.     'L;4': ('L;4', chr(4) + chr(0)),
  311.     'L': ('L', chr(8) + chr(0)),
  312.     'LA': ('LA', chr(8) + chr(4)),
  313.     'I': ('I;16B', chr(16) + chr(0)),
  314.     'P;1': ('P;1', chr(1) + chr(3)),
  315.     'P;2': ('P;2', chr(2) + chr(3)),
  316.     'P;4': ('P;4', chr(4) + chr(3)),
  317.     'P': ('P', chr(8) + chr(3)),
  318.     'RGB': ('RGB', chr(8) + chr(2)),
  319.     'RGBA': ('RGBA', chr(8) + chr(6)) }
  320.  
  321. def putchunk(fp, cid, *data):
  322.     data = string.join(data, '')
  323.     fp.write(o32(len(data)) + cid)
  324.     fp.write(data)
  325.     (hi, lo) = Image.core.crc32(data, Image.core.crc32(cid))
  326.     fp.write(o16(hi) + o16(lo))
  327.  
  328.  
  329. class _idat:
  330.     
  331.     def __init__(self, fp, chunk):
  332.         self.fp = fp
  333.         self.chunk = chunk
  334.  
  335.     
  336.     def write(self, data):
  337.         self.chunk(self.fp, 'IDAT', data)
  338.  
  339.  
  340.  
  341. def _save(im, fp, filename, chunk = putchunk, check = 0):
  342.     mode = im.mode
  343.     if mode == 'P':
  344.         if im.encoderinfo.has_key('bits'):
  345.             n = 1 << im.encoderinfo['bits']
  346.         else:
  347.             n = 256
  348.         if n <= 2:
  349.             bits = 1
  350.         elif n <= 4:
  351.             bits = 2
  352.         elif n <= 16:
  353.             bits = 4
  354.         else:
  355.             bits = 8
  356.         if bits != 8:
  357.             mode = '%s;%d' % (mode, bits)
  358.         
  359.     
  360.     if im.encoderinfo.has_key('dictionary'):
  361.         dictionary = im.encoderinfo['dictionary']
  362.     else:
  363.         dictionary = ''
  364.     im.encoderconfig = (im.encoderinfo.has_key('optimize'), dictionary)
  365.     
  366.     try:
  367.         (rawmode, mode) = _OUTMODES[mode]
  368.     except KeyError:
  369.         raise IOError, 'cannot write mode %s as PNG' % mode
  370.  
  371.     if check:
  372.         return check
  373.     
  374.     fp.write(_MAGIC)
  375.     chunk(fp, 'IHDR', o32(im.size[0]), o32(im.size[1]), mode, chr(0), chr(0), chr(0))
  376.     if im.mode == 'P':
  377.         chunk(fp, 'PLTE', im.im.getpalette('RGB'))
  378.     
  379.     if im.encoderinfo.has_key('transparency'):
  380.         if im.mode == 'P':
  381.             transparency = max(0, min(255, im.encoderinfo['transparency']))
  382.             chunk(fp, 'tRNS', chr(255) * transparency + chr(0))
  383.         elif im.mode == 'L':
  384.             transparency = max(0, min(65535, im.encoderinfo['transparency']))
  385.             chunk(fp, 'tRNS', o16(transparency))
  386.         else:
  387.             raise IOError, 'cannot use transparency for this mode'
  388.     
  389.     dpi = im.encoderinfo.get('dpi')
  390.     if dpi:
  391.         chunk(fp, 'pHYs', o32(int(dpi[0] / 0.0254 + 0.5)), o32(int(dpi[1] / 0.0254 + 0.5)), chr(1))
  392.     
  393.     info = im.encoderinfo.get('pnginfo')
  394.     if info:
  395.         for cid, data in info.chunks:
  396.             chunk(fp, cid, data)
  397.         
  398.     
  399.     ImageFile._save(im, _idat(fp, chunk), [
  400.         ('zip', (0, 0) + im.size, 0, rawmode)])
  401.     chunk(fp, 'IEND', '')
  402.     
  403.     try:
  404.         fp.flush()
  405.     except:
  406.         pass
  407.  
  408.  
  409.  
  410. def getchunks(im, **params):
  411.     
  412.     class collector:
  413.         data = []
  414.         
  415.         def write(self, data):
  416.             pass
  417.  
  418.         
  419.         def append(self, chunk):
  420.             self.data.append(chunk)
  421.  
  422.  
  423.     
  424.     def append(fp, cid, *data):
  425.         data = string.join(data, '')
  426.         (hi, lo) = Image.core.crc32(data, Image.core.crc32(cid))
  427.         crc = o16(hi) + o16(lo)
  428.         fp.append((cid, data, crc))
  429.  
  430.     fp = collector()
  431.     
  432.     try:
  433.         im.encoderinfo = params
  434.         _save(im, fp, None, append)
  435.     finally:
  436.         del im.encoderinfo
  437.  
  438.     return fp.data
  439.  
  440. Image.register_open('PNG', PngImageFile, _accept)
  441. Image.register_save('PNG', _save)
  442. Image.register_extension('PNG', '.png')
  443. Image.register_mime('PNG', 'image/png')
  444.